package com.maylann.ratiocheater.transform;

import com.maylann.ratiocheater.encoder.TorrentDictionary;
import com.maylann.ratiocheater.model.Announce;
import com.maylann.ratiocheater.model.Encoding;
import com.maylann.ratiocheater.model.Torrent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * by Maylann
 */
@Component
public class TorrentMapper {

    private static Logger LOGGER = LoggerFactory.getLogger(TorrentMapper.class);


    public Torrent map(TorrentDictionary<String, Object> in, String infoHash) throws TransformationException {
        //LOGGER.debug("mapping torrent file from dictionary to Torrent object");

        Announce announce = new Announce((String) in.get(TorrentDictionary.ANNOUNCE));

        String createdBy = transformElement(String.class, in, TorrentDictionary.CREATED_BY);
        Date creationDate = new Date(transformElement(Long.class, in, TorrentDictionary.CREATION_DATE));
        String encoding = transformElement(String.class, in, TorrentDictionary.ENCODING);
        String comment = transformElement(String.class, in, TorrentDictionary.COMMENT);

        TorrentDictionary<String, Object> infoDictionary = (TorrentDictionary<String, Object>) in.get(TorrentDictionary.INFO);

        String torrentName = transformElement(String.class, infoDictionary, TorrentDictionary.NAME);

        List<String> filenames = unwrapFilenames((List<Object>) infoDictionary.get(TorrentDictionary.FILES));

        return new Torrent(torrentName, announce, filenames, createdBy, creationDate, comment, infoHash, Encoding.getByValue(encoding));
    }

    private List<String> unwrapFilenames(List<Object> files) {
        List<String> filenames = new ArrayList<String>();
        for (Object object : files) {
            if (object instanceof TorrentDictionary) {
                String file = unwrapFilenames((TorrentDictionary<String, Object>) object);
                if (file != null) {
                    filenames.add(file);
                }
            }
        }
        return filenames;
    }

    private String unwrapFilenames(TorrentDictionary<String, Object> fileDictionary) {
        Object object = fileDictionary.get(TorrentDictionary.PATH);
        if (object instanceof List) {
            List<String> filepath = (List<String>) object;
            StringBuilder file = new StringBuilder();
            for (int i = 0; i < filepath.size(); i++) {
                String filePart = filepath.get(i);
                file.append(filePart);
                if (filepath.size() > 1 && i < filepath.size() - 1) {
                    file.append("/");
                }
            }
            return file.toString();
        }
        System.out.println("Unable to unwrap filename on object: " + object.getClass());
        return null;
    }

    private <T> T transformElement(Class<T> clazz, TorrentDictionary<String, Object> in, String key)
            throws TransformationException {
        Object encoding = in.get(key);
        if (encoding != null) {
            return (T) encoding;
        }
        throw new TransformationException("Error transforming " + key + ". Element missing in TorrentDictionary");
    }
}
